package com.mop.core.es.dao.dao;

import com.mop.core.es.dao.plugins.Pagination;
import com.mop.core.es.dao.plugins.aggs.Statistics;
import com.mop.core.es.dao.plugins.index.Mapping;
import com.mop.core.es.dao.plugins.index.Settings;
import com.mop.core.es.dao.plugins.wraper.QueryWraper;
import org.apache.poi.ss.formula.functions.T;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.List;

/**
 * @author lemon
 * @ClassName IElasticSearchDao
 * @desc es dao接口层
 * @Date 2018/12/12 16:33
 * @Version 1.0
 **/
public interface IElasticSearchDao {

    // ------------------------ 索引操作 API ------------------------

    /**
     * 创建索引<br />
     * @param index     索引名
     * @param settings  settings json字符串
     * @param mapping   mapping json字符串
     * @return
     */
    public boolean createIndex(String index, String settings, String mapping);

    /**
     * 创建索引<br />
     * settings 修改分片和副本数的<br />
     * mapping  修改字段和类型的<br >
     * @param index     索引名
     * @param settings  settings实体类
     * @param mapping   mapping实体类
     * @param <T>
     * @return
     */
    public <T> boolean createIndex(String index, Settings settings, Mapping mapping);

    /**
     * 根据索引名删除索引<br />
     * @param index 索引名
     * @return
     */
    public boolean deleteIndex(String index);

    /**
     * 根据索引名，判断索引是否存在<br />
     * @param index 索引名
     * @return
     */
    public boolean indexExists(String index);

    /**
     * 根据索引名刷新年索引<br />
     * @param indices   索引名
     * @return
     */
    public boolean flushIndices(String... indices);

    /**
     * 获取指定索引下文档结构<br />
     * @param index 索引名
     * @param type  文档名
     * @return
     */
    public String getMapping(String index, String type);

    // ------------------------ 索引操作 API ------------------------



    // ------------------------ 自定义Java实体类CURD API ------------------------

    /**
     * 插入单条文档<br />
     * docId的值为es文档中id的值
     * @param entity 带插入的实体类，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean insert(T entity);

    /**
     * 插入单条文档<br />
     * docId的值为es文档中id的值
     * @param index     索引名
     * @param type      文档名
     * @param entity    待插入的实体类，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean insert(String index, String type, T entity);

    /**
     * 批量插入文档
     * @param list  待插入实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkInsert(List<T> list);

    /**
     * 批量插入文档
     * @param index 索引名
     * @param type  文档名
     * @param list  待插入实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkInsert(String index, String type, List<T> list);


    /**
     * 根据docId，更新单条文档内容<br />
     * 值为null或者空的字段不更新<br />
     * docId的值为es文档中id的值
     * @param entity    待更新实体类，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean update(T entity);

    /**
     * 根据docId，更新单条文档内容<br />
     * 值为null或者空的字段不更新<br />
     * docId的值为es文档中id的值
     * @param index     索引名称
     * @param type      文档名
     * @param entity    待更新实体类，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean update(String index, String type, T entity);

    /**
     * 根据docId，批量更新文档内容<br />
     * 值为null或者空的字段不更新<br />
     * docId的值为es文档中id的值
     * @param list  待更新实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkUpdate(List<T> list);

    /**
     * 根据docId，批量更新文档内容<br />
     * 值为null或者空的字段不更新<br />
     * docId的值为es文档中id的值
     * @param index     索引名称
     * @param type      文档名称
     * @param list      待更新实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkUpdate(String index, String type, List<T> list);

    public <T> boolean insertOrUpdate(T entity);

    /**
     * 根据docId，删除单条文档<br />
     * docId的值为es文档中id的值
     * @param entity    待删除实体类，只需设置docId的值，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean delete(T entity);

    /**
     * 根据es文档中的id，删除单条文档<br />
     * @param index 索引名
     * @param type  文档名
     * @param id    文档id
     * @return
     */
    public boolean delete(String index, String type, String id);

    /**
     * 根据docId，批量删除文档<br />
     * docId的值为es文档中id的值
     * @param list  待删除实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkDelete(List<T> list);

    /**
     * 根据docId，批量删除文档<br />
     * docId的值为es文档中id的值
     * @param index 索引名
     * @param type  文档名
     * @param list  待删除实体类集合，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> boolean bulkDelete(String index, String type, List<T> list);


    /**
     * 根据docId，查询单条文档<br />
     * docId的值为es文档中id的值
     * @param entity    只需设置docId的值，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> T selectById(T entity);

    /**
     * 根据docId，查询单条文档<br />
     * docId的值为es文档中id的值
     * @param index     索引名
     * @param type      文档名
     * @param entity    只需设置docId的值，需要继承BaseESBean
     * @param <T>
     * @return
     */
    public <T> T selectById(String index, String type, T entity);

    /**
     * 根据自定义条件查询文档集合<br />
     * @param queryWraper   自定义查询包装类
     * @param <T>
     * @return
     */
    public <T> List<T> selectList(QueryWraper<T> queryWraper);

    /**
     * 根据自定义条件查询文档集合<br />
     * @param index 索引名
     * @param type  文档名
     * @param queryWraper   自定义查询包装类
     * @param <T>
     * @return
     */
    public <T> List<T> selectList(String index, String type, QueryWraper<T> queryWraper);

    /**
     * 根据分页条件，查询指定范围的文档集合<br />
     * 起始页默认从1开始<br />
     * @param pagination    分页实体类
     * @param <T>
     * @return
     */
    public <T> List<T> selectPage(Pagination pagination);

    /**
     * 根据分页条件，查询指定范围的文档集合<br />
     * 起始页默认从1开始<br />
     * @param index 索引名
     * @param type  文档名
     * @param pagination    分页实体类
     * @param <T>
     * @return
     */
    public <T> List<T> selectPage(String index, String type, Pagination pagination);

    // ------------------------ 自定义Java实体类CURD API ------------------------




    // ------------------------ 自定义Java实体类简单聚合 API ------------------------

    public <T> List<Statistics> selectAggs(QueryWraper<T> queryWraper);

    // ------------------------ 自定义Java实体类简单聚合 API ------------------------
}
